<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>时钟</title>
</head>
<style>
    canvas {
        background: #ccc
    }
</style>

<body>
    <canvas id="canvas"></canvas>
</body>
<script>
    //自动执行
    function clock() {
        //创建画布2d工作台
        var canvas = document.getElementById("canvas")
        var ctx = canvas.getContext("2d")

        //保存状态
        ctx.save()

        //清空画布（防止重复渲染）
        ctx.clearRect(0, 0, 150, 150)
        //平移
        ctx.translate(75, 75)
        //缩放大小
        ctx.scale(0.4, 0.4)
        //旋转角度，保证从1开始绘画
        ctx.rotate(-Math.PI / 2)
        //修改闹钟基础样式
        ctx.strokeStyle = "black"
        ctx.fillStyle = "white"
        ctx.lineWidth = 8
        ctx.lineCap = "round"

        //获取本地时间
        var date = new Date()

        //时针刻度
        ctx.save()
        //按照12小时制进行划分，共12个小时刻度
        for (var i = 0; i < 12; i++) {
            //开始绘画
            ctx.beginPath()
            ctx.rotate(Math.PI / 6)
            ctx.moveTo(100, 0)
            ctx.lineTo(120, 0)
            //描边
            ctx.stroke()
        }
        ctx.restore()

        //分针刻度
        ctx.save()
        //一圈一个小时，一个小时360度60分钟，180度30分钟
        //调整分针样式
        ctx.linewidth = 5
        for (var i = 0; i < 60; i++) {
            //去掉5分钟的刻度，留出空隙放小时刻度
            if (i % 5 != 0) {
                //开始绘画
                ctx.beginPath()
                ctx.rotate(Math.PI / 6)
                ctx.moveTo(117, 0)
                ctx.lineTo(120, 0)
                //描边
                ctx.stroke()
            }
            ctx.rotate(Math.PI / 30)
        }
        ctx.restore()

        //获取具体的时分秒
        var hours = date.getHours()
        var min = date.getMinutes()
        var sec = date.getSeconds()
        //将24小时制转换为12小时制
        hours = hours >= 12 ? hours - 12 : hours
        //改变颜色
        ctx.fillStyle = "black"


        //时针
        ctx.save()    //小时转动角度             分钟转动角度              秒钟转动角度
        ctx.rotate(hours * (Math.PI / 6) + (Math.PI / 360) * min + (Math.PI / 21600) * sec)
        ctx.lineWidth = 14
        //开始绘画
        ctx.beginPath()
        ctx.moveTo(-20, 0)
        ctx.lineTo(60, 0)
        //描边
        ctx.stroke()
        ctx.restore()

        //分针
        ctx.save()
        ctx.rotate((Math.PI / 30) * min + (Math.PI / 1800) * sec)
        ctx.lineWidth = 10;
        //开始绘画
        ctx.beginPath()
        ctx.moveTo(-28, 0)
        ctx.lineTo(80, 0)
        //描边
        ctx.stroke()
        ctx.restore()

        //秒针
        ctx.save()
        ctx.rotate((Math.PI / 1800) * sec)
        ctx.lineWidth = 6;
        ctx.strokeStyle = "#D40000";
        ctx.fillStyle = "#D40000";
        //开始绘画
        ctx.beginPath()
        ctx.moveTo(-30, 0)
        ctx.lineTo(83, 0)
        //描边
        ctx.stroke()
        //画中心点圆圈
        ctx.beginPath();
        ctx.arc(0, 0, 10, 0, Math.PI * 2, true);
        ctx.fill();
        //画指针对外侧圆圈
        ctx.beginPath();
        ctx.arc(95, 0, 10, 0, Math.PI * 2, true);
        ctx.stroke();
        //填充中心圆圈
        ctx.fillStyle = "rgba(0,0,0,0)";
        ctx.arc(0, 0, 3, 0, Math.PI * 2, true);
        ctx.fill();
        ctx.restore();

        //最外层蓝色圈
        ctx.beginPath();
        ctx.lineWidth = 14;
        ctx.strokeStyle = '#325FA2';
        ctx.arc(0, 0, 142, 0, Math.PI * 2, true);
        ctx.stroke();

        //window.requestAnimationFrame() 告诉浏览器——你希望执行一个动画，
        //并且要求浏览器在下次重绘之前调用指定的回调函数更新动画。
        //该方法需要传入一个回调函数作为参数，该回调函数会在浏览器下一次重绘之前执行
        window.requestAnimationFrame(clock);
    }
    window.requestAnimationFrame(clock)
</script>

</html>